#ifndef LOGGER_H
#define LOGGER_H

#include <iostream>
#include <string>
#include <chrono>
#include <fstream>
#include <mutex>
#include <ctime>
#include <iomanip>
#include <sstream>

// 日志级别枚举
enum LogLevel {
    DEBUG,
    INFO,
    WARNING,
    ERROR
};

class Logger {
public:
    // 获取单例实例
    static Logger& getInstance();

    // 设置日志级别
    void setLogLevel(LogLevel level);

    // 获取当前日志级别
    LogLevel getLogLevel() const;

    // 设置是否输出到控制台
    void setConsoleOutput(bool enabled);

    // 设置是否输出到文件
    void setFileOutput(bool enabled, const std::string& filename = "gb_client.log");

    // 记录日志的主要方法
    void log(LogLevel level, const std::string& file, int line, const std::string& function, const std::string& message);

    // 获取日志级别的字符串表示
    static std::string getLevelString(LogLevel level);

    // 获取当前时间的字符串表示
    static std::string getCurrentTimeString();

private:
    // 私有构造函数（单例模式）
    Logger();
    
    // 禁止拷贝和赋值
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;

    LogLevel currentLevel;
    bool consoleOutput;
    bool fileOutput;
    std::string logFilename;
    std::mutex logMutex;
    std::ofstream logFile;

    static LogLevel currentLevel;
    static std::ofstream logFile;
    static std::mutex logMutex;
    
    static std::string levelToString(LogLevel level) {
        switch (level) {
            case DEBUG: return "DEBUG";
            case INFO: return "INFO ";
            case WARNING: return "WARN ";
            case ERROR: return "ERROR";
            default: return "UNKNOWN";
        }
    }
    
    static std::string getCurrentTime() {
        auto now = std::chrono::system_clock::now();
        auto now_c = std::chrono::system_clock::to_time_t(now);
        struct tm timeinfo;
        
        #ifdef _WIN32
        localtime_s(&timeinfo, &now_c);
        #else
        localtime_r(&now_c, &timeinfo);
        #endif
        
        std::ostringstream oss;
        oss << std::put_time(&timeinfo, "%Y-%m-%d %H:%M:%S");
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()) % 1000;
        oss << "." << std::setfill('0') << std::setw(3) << ms.count();
        return oss.str();
    }
    
    static void log(LogLevel level, const std::string& message) {
        if (level < currentLevel) return;
        
        std::lock_guard<std::mutex> lock(logMutex);
        std::string timeStr = getCurrentTime();
        std::string logMsg = timeStr + " [" + levelToString(level) + "] " + message;
        
        std::cout << logMsg << std::endl;
        
        if (logFile.is_open()) {
            logFile << logMsg << std::endl;
            logFile.flush();
        }
    }
};

// 便捷的日志宏定义
#define LOG_TRACE(message) Logger::getInstance().log(TRACE, __FILE__, __LINE__, __FUNCTION__, message)
#define LOG_DEBUG(message) Logger::getInstance().log(DEBUG, __FILE__, __LINE__, __FUNCTION__, message)
#define LOG_INFO(message)  Logger::getInstance().log(INFO, __FILE__, __LINE__, __FUNCTION__, message)
#define LOG_WARN(message)  Logger::getInstance().log(WARN, __FILE__, __LINE__, __FUNCTION__, message)
#define LOG_ERROR(message) Logger::getInstance().log(ERROR, __FILE__, __LINE__, __FUNCTION__, message)
#define LOG_FATAL(message) Logger::getInstance().log(FATAL, __FILE__, __LINE__, __FUNCTION__, message)

#endif // LOGGER_H 